// Copyright (c) 2022 Presto Labs Pte. Ltd.
// Author: ziyan

#pragma once

#include <iomanip>
#include <sstream>
#include <string>
#include <vector>

#include "coin2/base/time.h"
#include "coin2/exchange/feed.pb.h"

struct VolumePerExchange {
  std::string exchange_name;
  double volume;
  double volume_in_usd;
  VolumePerExchange() = default;
  VolumePerExchange(std::string exchange_name, double volume, double volume_in_usd)
    : exchange_name(exchange_name), volume(volume), volume_in_usd(volume_in_usd) {}
};

struct MarketAnalysis {
  int64_t timestamp;
  double total_supply;
  double max_supply;
  double circulating_supply;
  double market_cap_in_usd;
  double tvl_in_usd;
  double total_volume_in_usd;
  std::vector<VolumePerExchange> volume_per_exchange_list;

  void Clear() {
    timestamp = 0;
    total_supply = 0;
    max_supply = 0;
    circulating_supply = 0;
    market_cap_in_usd = 0;
    tvl_in_usd = 0;
    total_volume_in_usd = 0;
    volume_per_exchange_list.clear();
  }
};

inline std::ostream& operator<<(
    std::ostream& os,
    const VolumePerExchange& volume_per_exchange) {
  os << "(exchange_name:";
  os << volume_per_exchange.exchange_name;
  os << ",volume:";
  os << std::setw(10);
  os << volume_per_exchange.volume;
  os << ",volume_in_usd:";
  os << std::setw(10);
  os << volume_per_exchange.volume_in_usd;
  os << ")";
  return os;
}

inline std::ostream& operator<<(
    std::ostream& os,
    const MarketAnalysis& market_analysis) {
  os << "Market analysis";
  os << "(total_supply:";
  os << std::setw(10);
  os << market_analysis.total_supply;
  os << ",max_supply:";
  os << std::setw(10);
  os << market_analysis.max_supply;
  os << ",circulating_supply:";
  os << std::setw(10);
  os << market_analysis.circulating_supply;
  os << ",market_cap_in_usd:";
  os << std::setw(10);
  os << market_analysis.market_cap_in_usd;
  os << ",tvl_in_usd:";
  os << std::setw(10);
  os << market_analysis.tvl_in_usd;
  os << ",total_volume_in_usd:";
  os << std::setw(10);
  os << market_analysis.total_volume_in_usd;
  os << ",volume_per_exchange:(";
  for (auto it = market_analysis.volume_per_exchange_list.begin(); it != market_analysis.volume_per_exchange_list.end(); it++) {
    if (it != market_analysis.volume_per_exchange_list.begin()) {
      os << ",";
    }
    os << *it;
  }
  os << "))";
  return os;
}
